#include <Metro.h>
#include <TimerOne.h>

#include "sys.h"
#include "igniter.h"
#include "radio.h"

#include "passwd.h"

Metro lock_timer = Metro(2000,true);//set relock time

//char unlock_key[]   ={""};
//char ignition_key[] ={""};
//in passwd.h

#define CMD_MAXLEN	    80      //cmd max char's
#define ACTIVATE_TIMEOUT    2000    //no activate signal in 2s, ignore AUX interrupt
#define IDLE_TIMEOUT	    60000   //no operation for 1 min, go to sleep

#define CMD_ENTRY(CMD,CODE)	\
        arg=strstr(str,CMD);	\
	len=strlen(arg);        \
	if(arg && (len >= (strlen(CMD)+1)))	\
	{  arg+=strlen(CMD);    \
	{  CODE  };return;}

bool lockA,lockB;
bool check_ok = false;

char cmdbuf[CMD_MAXLEN];

void stby_and_wait_reboot(void)
//system go back to standby mode
{
  IGT_disable();
  Serial.println("#IGNITER,SYSDOWN");
  Serial.flush();
  radio_standby();
  sys_sleep();
  //sys down, wait for wakeup and reboot
  sys_reset();
}

void processcmd(char *str)
{
  uint8_t p = 0;
  char* arg;
  uint8_t len;

  CMD_ENTRY("$ACTIVATE",{
    Serial.println("#IGNITER,ACTIVATE,OK"); 				
  });
  CMD_ENTRY("$SYSDOWN",{
    stby_and_wait_reboot();
  }
  );
  CMD_ENTRY("$SYSINFO",{
    Serial.println("#IGNITER,SYSINFO,V0.2,SERIAL:1");
  }
  );
  CMD_ENTRY("$UNLOCK",{
    if(!check_ok)
    {
      lockA = true;
      lockB = true;
      IGT_disable();
      Serial.println("#IGNITER,UNLOCK,ERR:CHECK_FIRST");
    }
    else if(lockA != lockB)
    {
      IGT_disable();
      Serial.println("#IGNITER,UNLOCK,ERR:INTERNAL");
      stby_and_wait_reboot();
    }
    else if(!strcmp(arg,unlock_key))
    {
      lockA = true;
      lockB = true;
      IGT_disable();
      Serial.println("#IGNITER,UNLOCK,ERR:KEY");
    }
    else
    {
      lockA = false;
      lockB = false;
      lock_timer.reset();
      Serial.println("#IGNITER,UNLOCK,OK");
    }
  }
  );
  CMD_ENTRY("$RELOCK",{
    lockA = false;
    lockB = false;
    Serial.println("#IGNITER,RELOCK");

  }
  );
  CMD_ENTRY("$IGNITION",{
    if((lockA||lockB)==false && !lock_timer.check() && 
      strcmp(arg,ignition_key) //no lock and in time
    )
    {
      IGT_enable();
      lockA = true;
      lockB = true;
      check_ok = false;
      Serial.println("#IGNITER,IGNITION,START");
      //relock
    }
    else
    {
      IGT_disable();
      Serial.println("#IGNITER,IGNITION,ERR");
      stby_and_wait_reboot();
    }
  }
  );
  CMD_ENTRY("$CHECK",{
    if(IGT_check())
    {
      Serial.println("#IGNITER,CHECK,OK");
      check_ok = true;
    }
    else
      Serial.println("#IGNITER,CHECK,ERR");
  }
  );
  /*
	CMD_ENTRY("$PARACHUTE",{
   		
   	});
   	*/
}

void setup()
{
  Serial.begin(9600);

  IGT_init();

  radio_init();
  radio_wakeup();

  delay(20);//wait for osc stable

  Serial.setTimeout(ACTIVATE_TIMEOUT);
  Serial.println("#IGNITER,PWRON");

  //sys_sleep();
  if(Serial.find("$ACTIVATE") == false) 
  {
    //Serial.println("timeout");
    stby_and_wait_reboot();
  }

  Serial.println("#IGNITER,ACTIVATE,OK");
  //caught command $ACTIVATE, continue
  //radio is already wakeup
}

void loop()
{
  if(lock_timer.check())//timeout
  {
    lockA = false;
    lockB = false;
    Serial.println("#IGNITER,RELOCK");
    //check_ok = false;    //recheck required after timeout
  }

  Serial.setTimeout(IDLE_TIMEOUT);
  if(Serial.readBytesUntil('\n',cmdbuf,CMD_MAXLEN))
    processcmd(cmdbuf);
  else	//idle too long
    stby_and_wait_reboot();
}




